/*
 * Component Unit Tests - 组件单元测试框架
 * 文档保存目录：/e:/DEV_VISION/frontend/static/js/tests/component-tests.js
 *
 * 功能说明：
 *   1. 测试FixedQueryArea.js - 查询区组件
 *   2. 测试QueryResultTable.js - 结果表格组件  
 *   3. 测试StudentInfoBar.js - 学生信息栏组件
 *   4. 验证配置驱动架构的完整性
 *   5. 确保组件接口的正确性和稳定性
 *
 * 使用方法：
 *   1. 在浏览器控制台运行：runAllComponentTests()
 *   2. 单独测试组件：runFixedQueryAreaTests()、runQueryResultTableTests()、runStudentInfoBarTests()
 *   3. 查看测试报告：getTestReport()
 */

// 测试框架全局变量
let testResults = {
  fixedQueryArea: [],
  queryResultTable: [],
  studentInfoBar: [],
  startTime: null,
  endTime: null
};

// 测试工具函数
const TestUtils = {
  // 创建测试容器
  createTestContainer(id) {
    const container = document.createElement('div');
    container.id = id;
    container.style.display = 'none'; // 隐藏测试容器
    document.body.appendChild(container);
    return container;
  },

  // 清理测试容器
  cleanupTestContainer(id) {
    const container = document.getElementById(id);
    if (container) {
      container.remove();
    }
  },

  // 模拟API响应
  mockFetch(url, response) {
    const originalFetch = window.fetch;
    window.fetch = function(requestUrl) {
      if (requestUrl.includes(url)) {
        return Promise.resolve({
          ok: true,
          json: () => Promise.resolve(response)
        });
      }
      return originalFetch.apply(this, arguments);
    };
    return originalFetch;
  },

  // 恢复原始fetch
  restoreFetch(originalFetch) {
    window.fetch = originalFetch;
  },

  // 断言函数
  assert(condition, message) {
    if (!condition) {
      throw new Error(`断言失败: ${message}`);
    }
  },

  // 等待异步操作
  async wait(ms = 100) {
    return new Promise(resolve => setTimeout(resolve, ms));
  },

  // 记录测试结果
  recordTest(component, testName, success, error = null, duration = 0) {
    testResults[component].push({
      name: testName,
      success,
      error: error ? error.message : null,
      duration
    });
  }
};

// =========================
// FixedQueryArea 组件测试
// =========================

async function runFixedQueryAreaTests() {
  console.log('🧪 开始测试 FixedQueryArea 组件...');
  
  // 测试1: 基本渲染功能
  await testFixedQueryAreaRender();
  
  // 测试2: 配置驱动功能
  await testFixedQueryAreaConfig();
  
  // 测试3: 事件绑定功能
  await testFixedQueryAreaEvents();
  
  // 测试4: 错误处理功能
  await testFixedQueryAreaErrorHandling();
  
  console.log('✅ FixedQueryArea 组件测试完成');
}

async function testFixedQueryAreaRender() {
  const testName = 'FixedQueryArea基本渲染测试';
  const startTime = Date.now();
  
  try {
    // 创建测试容器
    const container = TestUtils.createTestContainer('test-fixed-query-area');
    
    // 模拟配置数据
    const mockConfig = [
      { field: 'name', display_name: '姓名', input_type: 'text' },
      { field: 'school', display_name: '学校', input_type: 'select', options: [
        { value: '华兴小学', label: '华兴小学' }
      ]}
    ];
    
    // 模拟回调函数
    let searchCalled = false;
    let clearCalled = false;
    const onSearch = (params) => { searchCalled = true; };
    const onClear = () => { clearCalled = true; };
    
    // 测试渲染
    if (window.renderFixedQueryArea) {
      window.renderFixedQueryArea(mockConfig, 'test-fixed-query-area', onSearch, onClear);
      
      await TestUtils.wait(50);
      
      // 验证渲染结果
      const form = container.querySelector('form');
      TestUtils.assert(form !== null, '应该渲染表单元素');
      
      const nameInput = container.querySelector('input[name="name"]');
      TestUtils.assert(nameInput !== null, '应该渲染姓名输入框');
      
      const schoolSelect = container.querySelector('select[name="school"]');
      TestUtils.assert(schoolSelect !== null, '应该渲染学校下拉框');
      
      const searchBtn = container.querySelector('button[type="submit"]');
      TestUtils.assert(searchBtn !== null, '应该渲染查询按钮');
      
      console.log('✅ FixedQueryArea渲染测试通过');
      TestUtils.recordTest('fixedQueryArea', testName, true, null, Date.now() - startTime);
    } else {
      throw new Error('FixedQueryArea组件未加载');
    }
    
    // 清理
    TestUtils.cleanupTestContainer('test-fixed-query-area');
    
  } catch (error) {
    console.error('❌ FixedQueryArea渲染测试失败:', error);
    TestUtils.recordTest('fixedQueryArea', testName, false, error, Date.now() - startTime);
  }
}

async function testFixedQueryAreaConfig() {
  const testName = 'FixedQueryArea配置驱动测试';
  const startTime = Date.now();
  
  try {
    // 测试宽度配置
    const container = TestUtils.createTestContainer('test-fixed-query-config');
    
    const configWithWidth = [
      { field: 'test', display_name: '测试字段', input_type: 'text', width: 200 }
    ];
    
    window.renderFixedQueryArea(configWithWidth, 'test-fixed-query-config', () => {}, () => {});
    
    await TestUtils.wait(50);
    
    const input = container.querySelector('input[name="test"]');
    TestUtils.assert(input !== null, '应该渲染测试输入框');
    TestUtils.assert(input.style.width === '200px', '应该应用配置的宽度');
    
    console.log('✅ FixedQueryArea配置驱动测试通过');
    TestUtils.recordTest('fixedQueryArea', testName, true, null, Date.now() - startTime);
    
    TestUtils.cleanupTestContainer('test-fixed-query-config');
    
  } catch (error) {
    console.error('❌ FixedQueryArea配置驱动测试失败:', error);
    TestUtils.recordTest('fixedQueryArea', testName, false, error, Date.now() - startTime);
  }
}

async function testFixedQueryAreaEvents() {
  const testName = 'FixedQueryArea事件绑定测试';
  const startTime = Date.now();
  
  try {
    const container = TestUtils.createTestContainer('test-fixed-query-events');
    
    let searchParams = null;
    let clearCalled = false;
    
    const mockConfig = [
      { field: 'test', display_name: '测试', input_type: 'text' }
    ];
    
    const onSearch = (params) => { searchParams = params; };
    const onClear = () => { clearCalled = true; };
    
    window.renderFixedQueryArea(mockConfig, 'test-fixed-query-events', onSearch, onClear);
    
    await TestUtils.wait(50);
    
    // 测试输入和提交
    const input = container.querySelector('input[name="test"]');
    const form = container.querySelector('form');
    const clearBtn = container.querySelector('button[type="button"]');
    
    input.value = '测试值';
    
    // 模拟表单提交
    const submitEvent = new Event('submit');
    form.dispatchEvent(submitEvent);
    
    await TestUtils.wait(50);
    
    TestUtils.assert(searchParams !== null, '搜索回调应该被调用');
    TestUtils.assert(searchParams.test === '测试值', '应该收集正确的参数');
    
    // 测试清除按钮
    clearBtn.click();
    await TestUtils.wait(50);
    
    TestUtils.assert(clearCalled === true, '清除回调应该被调用');
    TestUtils.assert(input.value === '', '输入框应该被清空');
    
    console.log('✅ FixedQueryArea事件绑定测试通过');
    TestUtils.recordTest('fixedQueryArea', testName, true, null, Date.now() - startTime);
    
    TestUtils.cleanupTestContainer('test-fixed-query-events');
    
  } catch (error) {
    console.error('❌ FixedQueryArea事件绑定测试失败:', error);
    TestUtils.recordTest('fixedQueryArea', testName, false, error, Date.now() - startTime);
  }
}

async function testFixedQueryAreaErrorHandling() {
  const testName = 'FixedQueryArea错误处理测试';
  const startTime = Date.now();
  
  try {
    // 测试无效配置处理
    TestUtils.createTestContainer('test-fixed-query-error');
    
    // 测试应该不会抛出错误
    window.renderFixedQueryArea(null, 'test-fixed-query-error', () => {}, () => {});
    window.renderFixedQueryArea([], 'test-fixed-query-error', () => {}, () => {});
    
    console.log('✅ FixedQueryArea错误处理测试通过');
    TestUtils.recordTest('fixedQueryArea', testName, true, null, Date.now() - startTime);
    
    TestUtils.cleanupTestContainer('test-fixed-query-error');
    
  } catch (error) {
    console.error('❌ FixedQueryArea错误处理测试失败:', error);
    TestUtils.recordTest('fixedQueryArea', testName, false, error, Date.now() - startTime);
  }
}

// =========================
// QueryResultTable 组件测试
// =========================

async function runQueryResultTableTests() {
  console.log('🧪 开始测试 QueryResultTable 组件...');
  
  // 测试1: 基本渲染功能
  await testQueryResultTableRender();
  
  // 测试2: 配置驱动功能
  await testQueryResultTableConfig();
  
  // 测试3: 操作按钮功能
  await testQueryResultTableActions();
  
  // 测试4: 错误处理功能
  await testQueryResultTableErrorHandling();
  
  console.log('✅ QueryResultTable 组件测试完成');
}

async function testQueryResultTableRender() {
  const testName = 'QueryResultTable基本渲染测试';
  const startTime = Date.now();
  
  try {
    // 创建测试DOM结构
    const container = TestUtils.createTestContainer('test-query-result');
    container.innerHTML = `
      <table>
        <thead id="queryTableHead"></thead>
        <tbody id="queryTableBody"></tbody>
      </table>
    `;
    
    // 模拟API响应
    const originalFetch = TestUtils.mockFetch('/api/config/search_result_fields/', {
      success: true,
      fields: [
        { field: 'name', display_name: '姓名' },
        { field: 'school', display_name: '学校' }
      ]
    });
    
    // 模拟数据
    const mockData = [
      { name: '张三', school: '华兴小学', student_id: 1 },
      { name: '李四', school: '苏宁小学', student_id: 2 }
    ];
    
    // 测试渲染
    if (window.renderQueryResultTable) {
      await window.renderQueryResultTable(mockData, 'vision', 'query');
      
      await TestUtils.wait(100);
      
      // 验证表头
      const thead = container.querySelector('#queryTableHead');
      const headerCells = thead.querySelectorAll('th');
      TestUtils.assert(headerCells.length >= 2, '应该渲染表头');
      
      // 验证表体
      const tbody = container.querySelector('#queryTableBody');
      const rows = tbody.querySelectorAll('tr');
      TestUtils.assert(rows.length === 2, '应该渲染2行数据');
      
      console.log('✅ QueryResultTable渲染测试通过');
      TestUtils.recordTest('queryResultTable', testName, true, null, Date.now() - startTime);
    } else {
      throw new Error('QueryResultTable组件未加载');
    }
    
    // 恢复fetch
    TestUtils.restoreFetch(originalFetch);
    TestUtils.cleanupTestContainer('test-query-result');
    
  } catch (error) {
    console.error('❌ QueryResultTable渲染测试失败:', error);
    TestUtils.recordTest('queryResultTable', testName, false, error, Date.now() - startTime);
  }
}

async function testQueryResultTableConfig() {
  const testName = 'QueryResultTable配置驱动测试';
  const startTime = Date.now();
  
  try {
    const container = TestUtils.createTestContainer('test-query-result-config');
    container.innerHTML = `
      <table>
        <thead id="queryTableHead"></thead>
        <tbody id="queryTableBody"></tbody>
      </table>
    `;
    
    // 测试自定义操作按钮配置
    const customActions = [
      { text: '自定义操作', handler: 'customHandler', className: 'btn btn-custom' }
    ];
    
    const originalFetch = TestUtils.mockFetch('/api/config/search_result_fields/', {
      success: true,
      fields: [{ field: 'name', display_name: '姓名' }]
    });
    
    await window.renderQueryResultTable(
      [{ name: '测试', student_id: 1 }], 
      'test', 
      'query',
      { actions: customActions }
    );
    
    await TestUtils.wait(100);
    
    // 验证自定义按钮
    const customBtn = container.querySelector('.btn-custom');
    TestUtils.assert(customBtn !== null, '应该渲染自定义操作按钮');
    
    console.log('✅ QueryResultTable配置驱动测试通过');
    TestUtils.recordTest('queryResultTable', testName, true, null, Date.now() - startTime);
    
    TestUtils.restoreFetch(originalFetch);
    TestUtils.cleanupTestContainer('test-query-result-config');
    
  } catch (error) {
    console.error('❌ QueryResultTable配置驱动测试失败:', error);
    TestUtils.recordTest('queryResultTable', testName, false, error, Date.now() - startTime);
  }
}

async function testQueryResultTableActions() {
  const testName = 'QueryResultTable操作按钮测试';
  const startTime = Date.now();
  
  try {
    const container = TestUtils.createTestContainer('test-query-result-actions');
    container.innerHTML = `
      <table>
        <thead id="queryTableHead"></thead>
        <tbody id="queryTableBody"></tbody>
      </table>
    `;
    
    // 模拟全局处理函数
    let handlerCalled = false;
    window.testHandler = function(studentId) {
      handlerCalled = true;
      console.log('测试处理函数被调用:', studentId);
    };
    
    const customActions = [
      { text: '测试', handler: 'testHandler', className: 'btn btn-test' }
    ];
    
    const originalFetch = TestUtils.mockFetch('/api/config/search_result_fields/', {
      success: true,
      fields: [{ field: 'name', display_name: '姓名' }]
    });
    
    await window.renderQueryResultTable(
      [{ name: '测试学生', student_id: 123 }],
      'test',
      'query',
      { actions: customActions }
    );
    
    await TestUtils.wait(100);
    
    // 点击测试按钮
    const testBtn = container.querySelector('.btn-test');
    TestUtils.assert(testBtn !== null, '应该找到测试按钮');
    
    testBtn.click();
    await TestUtils.wait(50);
    
    TestUtils.assert(handlerCalled === true, '处理函数应该被调用');
    
    console.log('✅ QueryResultTable操作按钮测试通过');
    TestUtils.recordTest('queryResultTable', testName, true, null, Date.now() - startTime);
    
    // 清理
    delete window.testHandler;
    TestUtils.restoreFetch(originalFetch);
    TestUtils.cleanupTestContainer('test-query-result-actions');
    
  } catch (error) {
    console.error('❌ QueryResultTable操作按钮测试失败:', error);
    TestUtils.recordTest('queryResultTable', testName, false, error, Date.now() - startTime);
  }
}

async function testQueryResultTableErrorHandling() {
  const testName = 'QueryResultTable错误处理测试';
  const startTime = Date.now();
  
  try {
    const container = TestUtils.createTestContainer('test-query-result-error');
    container.innerHTML = `
      <table>
        <thead id="queryTableHead"></thead>
        <tbody id="queryTableBody"></tbody>
      </table>
    `;
    
    // 模拟API错误
    const originalFetch = TestUtils.mockFetch('/api/config/search_result_fields/', {
      success: false,
      error: '配置获取失败'
    });
    
    // 测试错误处理
    await window.renderQueryResultTable([], 'test', 'query');
    
    await TestUtils.wait(100);
    
    // 验证错误显示
    const tbody = container.querySelector('#queryTableBody');
    const errorRow = tbody.querySelector('tr');
    TestUtils.assert(errorRow !== null, '应该显示错误信息');
    
    console.log('✅ QueryResultTable错误处理测试通过');
    TestUtils.recordTest('queryResultTable', testName, true, null, Date.now() - startTime);
    
    TestUtils.restoreFetch(originalFetch);
    TestUtils.cleanupTestContainer('test-query-result-error');
    
  } catch (error) {
    console.error('❌ QueryResultTable错误处理测试失败:', error);
    TestUtils.recordTest('queryResultTable', testName, false, error, Date.now() - startTime);
  }
}

// =========================
// StudentInfoBar 组件测试
// =========================

async function runStudentInfoBarTests() {
  console.log('🧪 开始测试 StudentInfoBar 组件...');
  
  // 测试1: 基本渲染功能
  await testStudentInfoBarRender();
  
  // 测试2: 配置驱动功能
  await testStudentInfoBarConfig();
  
  // 测试3: 模块化配置
  await testStudentInfoBarModules();
  
  // 测试4: 错误处理功能
  await testStudentInfoBarErrorHandling();
  
  console.log('✅ StudentInfoBar 组件测试完成');
}

async function testStudentInfoBarRender() {
  const testName = 'StudentInfoBar基本渲染测试';
  const startTime = Date.now();
  
  try {
    const container = TestUtils.createTestContainer('test-student-info-bar');
    
    // 模拟API响应
    const originalFetch1 = TestUtils.mockFetch('/api/config/student_info_bar_fields/', {
      success: true,
      fields: ['name', 'school', 'grade', 'class_name']
    });
    
    const originalFetch2 = TestUtils.mockFetch('/api/config/all_field_config', {
      success: true,
      config: {
        student: {
          name: { display_name: '姓名' },
          school: { display_name: '学校' },
          grade: { display_name: '年级' },
          class_name: { display_name: '班级' }
        }
      }
    });
    
    // 模拟学生数据
    const studentData = {
      name: '张三',
      school: '华兴小学',
      grade: '三年级',
      class_name: '1班'
    };
    
    // 测试渲染
    if (window.renderStudentInfoBar) {
      await window.renderStudentInfoBar(studentData, {
        containerId: 'test-student-info-bar'
      });
      
      await TestUtils.wait(100);
      
      // 验证渲染结果
      const infoItems = container.querySelectorAll('.info-bar-item');
      TestUtils.assert(infoItems.length >= 3, '应该渲染信息项');
      
      const nameItem = container.querySelector('.field-name');
      TestUtils.assert(nameItem !== null, '应该渲染姓名字段');
      
      console.log('✅ StudentInfoBar渲染测试通过');
      TestUtils.recordTest('studentInfoBar', testName, true, null, Date.now() - startTime);
    } else {
      throw new Error('StudentInfoBar组件未加载');
    }
    
    TestUtils.restoreFetch(originalFetch1);
    TestUtils.restoreFetch(originalFetch2);
    TestUtils.cleanupTestContainer('test-student-info-bar');
    
  } catch (error) {
    console.error('❌ StudentInfoBar渲染测试失败:', error);
    TestUtils.recordTest('studentInfoBar', testName, false, error, Date.now() - startTime);
  }
}

async function testStudentInfoBarConfig() {
  const testName = 'StudentInfoBar配置驱动测试';
  const startTime = Date.now();
  
  try {
    const container = TestUtils.createTestContainer('test-student-info-config');
    
    // 测试自定义样式配置
    const customStyles = {
      itemClass: 'custom-item-class',
      itemStyle: { color: 'red' }
    };
    
    const originalFetch1 = TestUtils.mockFetch('/api/config/student_info_bar_fields/', {
      success: true,
      fields: ['name']
    });
    
    const originalFetch2 = TestUtils.mockFetch('/api/config/all_field_config', {
      success: true,
      config: {
        student: {
          name: { display_name: '姓名' }
        }
      }
    });
    
    await window.renderStudentInfoBar(
      { name: '测试学生' },
      {
        containerId: 'test-student-info-config',
        customStyles: customStyles
      }
    );
    
    await TestUtils.wait(100);
    
    // 验证自定义样式
    const customItem = container.querySelector('.custom-item-class');
    TestUtils.assert(customItem !== null, '应该应用自定义样式类');
    
    console.log('✅ StudentInfoBar配置驱动测试通过');
    TestUtils.recordTest('studentInfoBar', testName, true, null, Date.now() - startTime);
    
    TestUtils.restoreFetch(originalFetch1);
    TestUtils.restoreFetch(originalFetch2);
    TestUtils.cleanupTestContainer('test-student-info-config');
    
  } catch (error) {
    console.error('❌ StudentInfoBar配置驱动测试失败:', error);
    TestUtils.recordTest('studentInfoBar', testName, false, error, Date.now() - startTime);
  }
}

async function testStudentInfoBarModules() {
  const testName = 'StudentInfoBar模块化配置测试';
  const startTime = Date.now();
  
  try {
    const container = TestUtils.createTestContainer('test-student-info-modules');
    
    // 模拟视力模块特定配置
    const originalFetch = TestUtils.mockFetch('/api/config/student_info_bar_fields/vision', {
      success: true,
      fields: ['name', 'school', 'birthday']
    });
    
    const originalFetch2 = TestUtils.mockFetch('/api/config/all_field_config', {
      success: true,
      config: {
        student: {
          name: { display_name: '姓名' },
          school: { display_name: '学校' },
          birthday: { display_name: '出生日期' }
        }
      }
    });
    
    await window.renderStudentInfoBar(
      { name: '张三', school: '华兴小学', birthday: '2010-01-01' },
      {
        containerId: 'test-student-info-modules',
        moduleName: 'vision'
      }
    );
    
    await TestUtils.wait(100);
    
    const infoItems = container.querySelectorAll('.info-bar-item');
    TestUtils.assert(infoItems.length === 3, '应该渲染3个信息项');
    
    console.log('✅ StudentInfoBar模块化配置测试通过');
    TestUtils.recordTest('studentInfoBar', testName, true, null, Date.now() - startTime);
    
    TestUtils.restoreFetch(originalFetch);
    TestUtils.restoreFetch(originalFetch2);
    TestUtils.cleanupTestContainer('test-student-info-modules');
    
  } catch (error) {
    console.error('❌ StudentInfoBar模块化配置测试失败:', error);
    TestUtils.recordTest('studentInfoBar', testName, false, error, Date.now() - startTime);
  }
}

async function testStudentInfoBarErrorHandling() {
  const testName = 'StudentInfoBar错误处理测试';
  const startTime = Date.now();
  
  try {
    const container = TestUtils.createTestContainer('test-student-info-error');
    
    // 测试无效数据处理
    await window.renderStudentInfoBar(null, {
      containerId: 'test-student-info-error'
    });
    
    await TestUtils.wait(100);
    
    // 验证错误显示
    const errorAlert = container.querySelector('.alert-warning');
    TestUtils.assert(errorAlert !== null, '应该显示错误信息');
    
    console.log('✅ StudentInfoBar错误处理测试通过');
    TestUtils.recordTest('studentInfoBar', testName, true, null, Date.now() - startTime);
    
    TestUtils.cleanupTestContainer('test-student-info-error');
    
  } catch (error) {
    console.error('❌ StudentInfoBar错误处理测试失败:', error);
    TestUtils.recordTest('studentInfoBar', testName, false, error, Date.now() - startTime);
  }
}

// =========================
// 主测试函数
// =========================

async function runAllComponentTests() {
  console.log('🚀 开始运行所有组件测试...');
  testResults.startTime = new Date();
  
  // 清空之前的测试结果
  testResults.fixedQueryArea = [];
  testResults.queryResultTable = [];
  testResults.studentInfoBar = [];
  
  try {
    await runFixedQueryAreaTests();
    await runQueryResultTableTests();
    await runStudentInfoBarTests();
    
    testResults.endTime = new Date();
    
    console.log('✅ 所有组件测试完成');
    console.log('📊 测试报告:', getTestReport());
    
  } catch (error) {
    console.error('❌ 测试运行失败:', error);
    testResults.endTime = new Date();
  }
}

function getTestReport() {
  const report = {
    duration: testResults.endTime - testResults.startTime,
    summary: {
      total: 0,
      passed: 0,
      failed: 0
    },
    details: {}
  };
  
  // 统计各组件测试结果
  ['fixedQueryArea', 'queryResultTable', 'studentInfoBar'].forEach(component => {
    const tests = testResults[component];
    const passed = tests.filter(t => t.success).length;
    const failed = tests.filter(t => !t.success).length;
    
    report.summary.total += tests.length;
    report.summary.passed += passed;
    report.summary.failed += failed;
    
    report.details[component] = {
      total: tests.length,
      passed,
      failed,
      tests: tests
    };
  });
  
  report.summary.passRate = report.summary.total > 0 
    ? (report.summary.passed / report.summary.total * 100).toFixed(1) + '%'
    : '0%';
  
  return report;
}

// 导出到全局
window.runAllComponentTests = runAllComponentTests;
window.runFixedQueryAreaTests = runFixedQueryAreaTests;
window.runQueryResultTableTests = runQueryResultTableTests;
window.runStudentInfoBarTests = runStudentInfoBarTests;
window.getTestReport = getTestReport;

console.log('✅ 组件测试框架已加载'); 